// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "ModularGameMode.h"

#include "LyraGameMode.generated.h"

#define UE_API LYRAGAME_API

class AActor;
class AController;
class AGameModeBase;
class APawn;
class APlayerController;
class UClass;
class ULyraExperienceDefinition;
class ULyraPawnData;
class UObject;
struct FFrame;
struct FPrimaryAssetId;
enum class ECommonSessionOnlineMode : uint8;

/**
 * 登录后事件，在玩家或机器人加入游戏时触发，以及在无缝和非无缝旅行后触发
 *
 * 这在玩家完成初始化后调用
 */
DECLARE_MULTICAST_DELEGATE_TwoParams(FOnLyraGameModePlayerInitialized, AGameModeBase* /*GameMode*/, AController* /*NewPlayer*/);

/**
 * Lyra游戏模式基类
 *
 *	此项目使用的基础游戏模式类。
 */
UCLASS(MinimalAPI, Config = Game, Meta = (ShortTooltip = "此项目使用的基础游戏模式类。"))
class ALyraGameMode : public AModularGameModeBase
{
	GENERATED_BODY()

public:

	UE_API ALyraGameMode(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); // 构造函数

	UFUNCTION(BlueprintCallable, Category = "Lyra|Pawn")
	UE_API const ULyraPawnData* GetPawnDataForController(const AController* InController) const; // 获取控制器的Pawn数据

	//~AGameModeBase接口
	UE_API virtual void InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) override; // 初始化游戏
	UE_API virtual UClass* GetDefaultPawnClassForController_Implementation(AController* InController) override; // 获取控制器的默认Pawn类
	UE_API virtual APawn* SpawnDefaultPawnAtTransform_Implementation(AController* NewPlayer, const FTransform& SpawnTransform) override; // 在变换处生成默认Pawn
	UE_API virtual bool ShouldSpawnAtStartSpot(AController* Player) override; // 是否应在起始点生成
	UE_API virtual void HandleStartingNewPlayer_Implementation(APlayerController* NewPlayer) override; // 处理新玩家开始
	UE_API virtual AActor* ChoosePlayerStart_Implementation(AController* Player) override; // 选择玩家起始点
	UE_API virtual void FinishRestartPlayer(AController* NewPlayer, const FRotator& StartRotation) override; // 完成玩家重启
	UE_API virtual bool PlayerCanRestart_Implementation(APlayerController* Player) override; // 玩家是否可以重启
	UE_API virtual void InitGameState() override; // 初始化游戏状态
	UE_API virtual bool UpdatePlayerStartSpot(AController* Player, const FString& Portal, FString& OutErrorMessage) override; // 更新玩家起始点
	UE_API virtual void GenericPlayerInitialization(AController* NewPlayer) override; // 通用玩家初始化
	UE_API virtual void FailedToRestartPlayer(AController* NewPlayer) override; // 重启玩家失败
	//~End of AGameModeBase接口

	// 下一帧重启（重生）指定的玩家或机器人
	// - 如果bForceReset为true，控制器将在当前帧重置（放弃当前拥有的Pawn，如果有）
	UFUNCTION(BlueprintCallable)
	UE_API void RequestPlayerRestartNextFrame(AController* Controller, bool bForceReset = false); // 请求下一帧重启玩家

	// PlayerCanRestart的通用版本，可用于玩家机器人和玩家
	UE_API virtual bool ControllerCanRestart(AController* Controller); // 控制器是否可以重启

	// 玩家初始化时调用的委托，如上所述 
	FOnLyraGameModePlayerInitialized OnGameModePlayerInitialized; // 游戏模式玩家初始化委托

protected:	
	UE_API void OnExperienceLoaded(const ULyraExperienceDefinition* CurrentExperience); // 经验加载完成回调
	UE_API bool IsExperienceLoaded() const; // 检查经验是否已加载

	UE_API void OnMatchAssignmentGiven(FPrimaryAssetId ExperienceId, const FString& ExperienceIdSource); // 匹配分配给定回调

	UE_API void HandleMatchAssignmentIfNotExpectingOne(); // 处理匹配分配（如果不期望）

	UE_API bool TryDedicatedServerLogin(); // 尝试专用服务器登录
	UE_API void HostDedicatedServerMatch(ECommonSessionOnlineMode OnlineMode); // 托管专用服务器匹配

	UFUNCTION()
	UE_API void OnUserInitializedForDedicatedServer(const UCommonUserInfo* UserInfo, bool bSuccess, FText Error, ECommonUserPrivilege RequestedPrivilege, ECommonUserOnlineContext OnlineContext); // 专用服务器用户初始化回调
};

#undef UE_API